%%%-------------------------------------------------------------------
%% @doc elcache top level supervisor.
%% @end
%%%-------------------------------------------------------------------

-module(elcache_sup).

-behaviour(supervisor).

%% API
-export([
    start_link/0,
    start_worker/4,
    start_super/1,
    stop_super/1
]).

%% Supervisor callbacks
-export([init/1]).

%% Helper macro for declaring children of supervisor
%% 子程序类型是worker，超时时间自定义，默认5s
%% 子程序类型是supervisor,超时标记为infinity
-define(CHILD(Module, Function, Args), {Module, {Module, Function, Args}, permanent, 5000, worker, [Module]}).
-define(SUPER(Module, Function, Args), {Module, {Module, Function, Args}, permanent, 5000, supervisor, [Module]}).

%% 需要启动的子程序
-define (CHILDS, [
    {elcache, start_link, []}
]).
-define (SUPERS, []).

-define(SERVER, ?MODULE).

%%====================================================================
%% API functions
%%====================================================================

start_link() ->
    supervisor:start_link({local, ?SERVER}, ?MODULE, []).

%%====================================================================
%% Supervisor callbacks
%%====================================================================

%% Child :: {Id,StartFunc,Restart,Shutdown,Type,Modules}
init([]) ->
    Childs1 = [?CHILD(Mod, Fun, Args) || {Mod, Fun, Args} <- ?CHILDS],
    Supers1 = [?SUPER(Mod, Fun, Args) || {Mod, Fun, Args} <- ?SUPERS],
    Childs = Childs1 ++ Supers1,
    {ok, { {one_for_one, 1, 5}, Childs} }.

%%====================================================================
%% Internal functions
%%====================================================================

start_worker(Id, Mod, Fun, Args) ->
    supervisor:start_child(?MODULE, {Id, {Mod, Fun, Args}, permanent, 5000, worker, [Mod]}).

start_super(ChildId) ->
    supervisor:start_child(?MODULE, {
        ChildId,
        {elcache_service_sup, start_link, []},
        permanent, 5000, supervisor,
        % transient, infinity, supervisor,
        [elcache_service_sup]
    }).

stop_super(ChildId) when is_atom(ChildId) orelse is_pid(ChildId) ->
    supervisor:terminate_child(?MODULE, ChildId),
    supervisor:delete_child(?MODULE, ChildId).